package com.sneakxy.mybase4j.generator.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import com.sneakxy.mybase4j.generator.utils.StringExtUtils;

/**
 * 类字段
 * @author 潜行的青衣
 * @see
 */
public class ClassField {
	
	private Permission permission = Permission.PRIVATE;

	private List<Annotation> annotations = new ArrayList<Annotation>();
	
	private String name;
	
	private ClassType type;
	
	private String value;
	
	private boolean staticf = false;
	
	private boolean finalf = false;
	
	private String comment;
	
	private boolean setter = true;
	
	private boolean getter = true;
	
	private Object extra;

	private Object extraType;
	
	public ClassField(ClassType type, String name) {
		this.type = type;
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isSetter() {
		return this.isFinalf() ? false : setter;
	}

	public void setSetter(boolean setter) {
		this.setter = setter;
	}

	public boolean isGetter() {
		return getter;
	}

	public void setGetter(boolean getter) {
		this.getter = getter;
	}

	public ClassType getType() {
		return type;
	}

	public void setType(ClassType type) {
		this.type = type;
	}

	public boolean isStaticf() {
		return staticf;
	}

	public void setStaticf(boolean staticf) {
		this.staticf = staticf;
	}

	public boolean isFinalf() {
		return finalf;
	}

	public void setFinalf(boolean finalf) {
		this.finalf = finalf;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public Permission getPermission() {
		return permission;
	}

	public void setPermission(Permission permission) {
		this.permission = permission;
	}
	
	public Object getExtraType() {
		return extraType;
	}

	public void setExtraType(Object extraType) {
		this.extraType = extraType;
	}

	public Annotation addAnnotation(Annotation annotation) {
		this.annotations.add(annotation);
		return annotation;
	}
	
	public List<Type> getImportClassType() {
		List<Type> result = new ArrayList<Type>();
		result.addAll(this.annotations);
		result.add(this.type);
		return result;
	}
	
	public String toFieldString() {
		StringBuilder s = new StringBuilder();
		//注释
		if(StringUtils.isNoneBlank(this.comment)) {
			s.append("\t/**\r\n");
			s.append("\t * ").append(comment).append("\r\n");
			s.append("\t */\r\n");
		}
		//注解
		Iterator<Annotation> annit = annotations.iterator();
		while(annit.hasNext()) {
			s.append("\t").append(annit.next().toString(true)).append("\r\n");
		}
		s.append("\t");
		s.append(this.getPermission().value());
		if(this.isFinalf()) {
			s.append(" final");
		}
		if(this.isStaticf()) {
			s.append(" static");
		}
		s.append(" ").append(type.toString(true));
		s.append(" ").append(this.name);
		if(this.value != null) {
			s.append(" = ").append(this.value);
		}
		s.append(";");
		return s.toString();
	}
	
	public String toSetterString() {
		StringBuilder s = new StringBuilder();
		s.append("set").append(StringExtUtils.upperCaseFirstChar(this.name));
		ClassMethod method = new ClassMethod(s.toString());
		method.addArgument(new Argument(this.type, this.name));
		method.addCodeLine(new StringBuilder().append("this.").append(this.name).append(" = ").append(this.name).append(";").toString());
		return method.toMethodString();
	}
	
	public String toGetterString() {
		StringBuilder s = new StringBuilder();
		s.append("get").append(StringExtUtils.upperCaseFirstChar(this.name));
		ClassMethod method = new ClassMethod(s.toString());
		method.setReturnType(this.type);
		method.addCodeLine(new StringBuilder().append("return ").append(this.name).append(";").toString());
		return method.toMethodString();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder()
				.append(this.name)
				.append(new TypeExt(this.type)).toHashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if(obj == null) {
			return false;
		}
		if(obj == this) {
			return true;
		}
		if(!(obj instanceof ClassField)) {
			return false;
		}
		ClassField field = (ClassField) obj;
		return new EqualsBuilder().append(this.name, field.name)
			.append(new TypeExt(this.type), new TypeExt(field.type)).isEquals();
	}

	public Object getExtra() {
		return extra;
	}

	public void setExtra(Object extra) {
		this.extra = extra;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
	
}
